package com.iwdnb.gkgz.common.quota;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.iwdnb.gkgz.common.model.dto.StockDayData;
import com.iwdnb.gkgz.common.utils.BigDecimalUtils;
import lombok.Data;

/**
 * 赫尔均线
 */
public class HullMovingAverage {

    /**
     * 计算权重移动平均值（WMA）
     *
     * @param prices   股票价格数组
     * @param period   计算周期
     * @param startPos 开始计算的位置
     * @return WMA
     */
    private static double weightedMovingAverage(double[] prices, int period, int startPos) {
        double sum = 0.0;
        double weights = 0.0;
        for (int i = 0; i < period; i++) {
            sum += prices[startPos + i] * (period - i);
            weights += (period - i);
        }
        return sum / weights;
    }

    public static List<HullAverageData> calculateHMA(List<StockDayData> stockDayDataList) {
        return calculateHMA(stockDayDataList, 20);
    }

    /**
     * 计算布林线
     */
    public static List<HullAverageData> calculateHMA(List<StockDayData> stockDayDataList, int period) {
        double[] prices = new double[stockDayDataList.size()];
        String[] dates = new String[stockDayDataList.size()];

        for (int i = 0; i < stockDayDataList.size(); i++) {
            prices[i] = stockDayDataList.get(i).getClosePrice().doubleValue();
            dates[i] = stockDayDataList.get(i).getDate();
        }
        return calculateHMA(dates, prices, period);
    }

    /**
     * 计算赫尔均线（HMA）
     *
     * @param prices 股票价格数组
     * @param period 计算周期
     * @return HMA数组
     */
    public static List<HullAverageData> calculateHMA(String[] dates, double[] prices, int period) {
        List<HullAverageData> list = new ArrayList<>();
        double[] intermediateHMA = new double[prices.length];

        // 计算 WMA1 和 WMA2，并存储差值用于HMA的计算
        for (int i = period - 1; i < prices.length; i++) {
            double wmaFullPeriod = weightedMovingAverage(prices, period, i - period + 1);
            double wmaHalfPeriod = weightedMovingAverage(prices, period / 2, i - (period / 2) + 1);
            intermediateHMA[i] = 2 * wmaHalfPeriod - wmaFullPeriod;
        }

        // 计算HMA基于 intermediateHMA
        int hmaPeriod = (int)Math.sqrt(period);
        for (int i = hmaPeriod - 1; i < prices.length; i++) {
            if (intermediateHMA[i] != 0) {
                double price = weightedMovingAverage(intermediateHMA, hmaPeriod, i - hmaPeriod + 1);
                HullAverageData hullAverageData = new HullAverageData();
                hullAverageData.setDate(dates[i]);
                hullAverageData.setPrice(BigDecimalUtils.round(new BigDecimal(price)));
                double bias=calculateBIAS(prices[i],price);
                hullAverageData.setBias(BigDecimalUtils.round(new BigDecimal(bias)));
                list.add(hullAverageData);
            }
        }

        return list;
    }

    // 计算乖离率
    private static double calculateBIAS(double currentPrice, double hma) {
        return ((currentPrice - hma) / hma) * 100;
    }

    @Data
    public static class HullAverageData {
        private String date;
        private BigDecimal price;
        /**
         * 乖离率
         */
        private BigDecimal bias;
    }

    public static void main(String[] args) {
        String[] dates = {
            // 这里应该是实际的股票日期
        };
        double[] prices = {
            // 在这里插入实际的股票价格数据
        };
        int period = 9; // 指示计算HMA所需的周期

        List<HullAverageData> hmaResult = calculateHMA(dates, prices, period);
        for (int i = 0; i < hmaResult.size(); i++) {
            if (hmaResult.get(i) != null) {
                System.out.println("Day " + (i + 1) + " HMA: " + hmaResult.get(i).getPrice());
            }
        }
    }
}

